package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.SetmealDishMapper;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @Author 杨旭康
 * @Date 2022/10/27 23:57
 * @question:
 */

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 添加套餐 --> 套餐 菜品 开事务
     * @param setmealDto
     */
    @Override
    @Transactional
    public void saveWithDish(SetmealDto setmealDto) {

        //将套餐信息直接save
        this.save(setmealDto);

        //添加菜品 - 套餐菜品关系
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes = setmealDishes.stream().map((item) -> {
            //菜品关系中 套餐id无赋值 将套餐id设置上
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());

        //调用service完成添加
        setmealDishService.saveBatch(setmealDishes);
    }

    /**
     * 分页条件查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page<SetmealDto> pageR(int page, int pageSize, String name) {

        //setmeal分页条件
        Page<Setmeal> pageInfo = new Page<>(page,pageSize);
        //setmealDto分页条件
        Page<SetmealDto> setmealDtoPage = new Page<>();
        //模糊查询
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name),Setmeal::getName,name);
        //排序
        wrapper.orderByDesc(Setmeal::getUpdateTime);
        //setmeal分页信息
        this.page(pageInfo,wrapper);

        //想要的是dto的分页信息 包含分类名称 进行流的拷贝
        BeanUtils.copyProperties(pageInfo,setmealDtoPage,"records");
        //讲里面的东西挨个赋给dto 在加上分类名
        List<Setmeal> records = pageInfo.getRecords();

        List<SetmealDto> list = records.stream().map((item) -> {
            //创建一个dto空客
            SetmealDto setmealDto = new SetmealDto();
            //讲item拷贝给dto
            BeanUtils.copyProperties(item,setmealDto);

            //一会调用查询获取分类名
            Long categoryId = item.getCategoryId();
            Category category = categoryMapper.selectById(categoryId);
            String categoryName = category.getName();
            //赋值
            setmealDto.setCategoryName(categoryName);

            return setmealDto;
        }).collect(Collectors.toList());

        //设置list
        setmealDtoPage.setRecords(list);

        return setmealDtoPage;
    }

    /**
     * 套餐的删除/批量删除
     * 删除套餐:1.售卖状态 2.菜品不能删除
     * @param ids
     */
    @Override
    public void removeWithDish(List<Long> ids) {

        //1.先查看套餐的售卖状态
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        //状态为1则不能删除
        wrapper.eq(Setmeal::getStatus,1);
        wrapper.in(Setmeal::getId,ids);

        //调用count查看
        int count = this.count(wrapper);

        if (count > 0) {
            //删除中有售卖状态的 不能删除
            throw new CustomException("删除的套餐在售卖中无法进行删除!");
        }

        //直接进行删除即可
        this.removeByIds(ids);

        //删除菜品/套餐关系表中的数据
        //delete from setmeal_dish where setmeal_id in (1,2,3)
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getSetmealId,ids);
        //直接调用关系表删除
        setmealDishService.remove(queryWrapper);

    }

    /**
     * 修改套餐 -- 回显
     * @param id
     * @return
     */
    @Override
    public SetmealDto getByWithDish(Long id) {

        //创建一个空的dto对象 用于流的对拷
        SetmealDto setmealDto = new SetmealDto();
        //直接获取套餐数据
        Setmeal setmeal = this.getById(id);
        //进行拷贝
        BeanUtils.copyProperties(setmeal,setmealDto);

        //还有菜品数据没有拷贝 在套餐/菜品关系表
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> list = setmealDishService.list(wrapper);

        //直接设置值即可
        setmealDto.setSetmealDishes(list);

        return setmealDto;
    }

    /**
     * 修改套餐数据
     * @param setmealDto
     */
    @Override
    public void updateByWithDish(SetmealDto setmealDto) {

        //先将套餐数据修改
        this.updateById(setmealDto);

        //修改 关系数据(可以使用先删除后新增做 简单)
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId,setmealDto.getId());
        //1.删除套餐/菜品 关系数据
        setmealDishService.remove(wrapper);
        //2.重新新增套餐/菜品 关系数据
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes = setmealDishes.stream().map((item) -> {
            //新增后需要重新设置套餐id
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());
        setmealDishService.saveBatch(setmealDishes);

    }

    /**
     * 根据套餐分类展示套餐
     * @param setmeal
     * @return
     */
    @Override
    public List<Setmeal> listR(Setmeal setmeal) {

        //条件构造器
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        //进行两次等职比较和排序
        wrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
        wrapper.eq(Setmeal::getStatus, 1);
        wrapper.orderByDesc(Setmeal::getUpdateTime);

        //调用mapper查询 集合
        List<Setmeal> setmeals = setmealMapper.selectList(wrapper);

        return setmeals;
    }


}
